#include "BigInt.h"
#include <iostream>
#include <time.h>
#include <assert.h>
using namespace std;

int main()
{
	//SOTTRAZIONE
	BigInt natale("234534534");
	BigInt babbo ("2345345345");
	cout<<((natale-babbo)==BigInt(-2110810811))<<endl;
	assert(((natale-babbo)==BigInt(-2110810811)));
	cout<<endl;

	BigInt lol("93847534897583746536");
	BigInt lal("8432450");	
	BigInt r1("93847534897575314086");
	BigInt r2("-93847534897575314086");
	cout<<((lol-lal)==r1)<<endl;
	assert((lol-lal)==r1);
	cout<<((lal-lol)==r2)<<endl;
	assert((lal-lol)==r2);
	cout<<endl;

	BigInt lul(2147483647);
	BigInt lel(-1);
	BigInt r3("2147483648");
	BigInt r4("-2147483648");
	cout<<((lul-lel)==r3)<<endl;
	assert(((lul-lel)==r3));
	cout<<((lel-lul)==r4)<<endl;
	assert((lel-lul)==r4);
	cout<<endl;

	BigInt zero(0);
	BigInt uno(1);
	cout<<((uno-uno)==BigInt(0))<<endl;
	assert(((uno-uno)==BigInt(0)));

	cout<<((zero-uno) == BigInt(-1))<<endl;
	assert((zero-uno) == BigInt(-1));

	cout<<((zero-zero == BigInt(0)))<<endl;
	assert((zero-zero == BigInt(0)));

	cout<<((uno-zero)==BigInt(1))<<endl;
	assert((uno-zero)==BigInt(1));
	cout<<endl;

	BigInt pippo ("23453453453343434343453453453453");
	BigInt pluto ("23948279384728934729834729834798");
	cout<<((pippo-pluto)==BigInt("-494825931385500386381276381345"))<<endl;
	assert((pippo-pluto)==BigInt("-494825931385500386381276381345"));

	cout<<((pluto-pippo)==BigInt("494825931385500386381276381345"))<<endl;
	assert((pluto-pippo)==BigInt("494825931385500386381276381345"));
	cout<<endl;

	BigInt lullalo ("2147483647");
	for(int i=0; i<100; ++i)
	{
		++lullalo;
	}
	cout<<(lullalo==BigInt("2147483747"))<<endl;
	assert(lullalo==BigInt("2147483747"));
	cout<<endl;

	BigInt t1 ("-44143143141414343");
	BigInt t2 ("-546364725645617451");
	BigInt sss = t1+t2;
	cout<<(sss==BigInt("-590507868787031794"))<<endl;
	cout<<endl;

	BigInt meno ("-3428975289347289347234656352462542783487234289347289374832974298347293847289374");
	BigInt piu ("3428975289347289347234656352462542783487234289347289374832974298347293847289374");
	BigInt fastprintami = meno - piu;
	cout<<((fastprintami + piu)==meno)<<endl;
	assert((fastprintami + piu)==meno);

	fastprintami = piu - meno;
	cout<<((fastprintami + meno)==piu)<<endl;
	assert((fastprintami + meno)==piu);

	cout<<((meno-meno)==BigInt(0))<<endl;
	assert((meno-meno)==BigInt(0));

	cout<<((piu-piu)==BigInt(0))<<endl;
	assert((piu-piu)==BigInt(0));
	cout<<endl;

	BigInt sad ("2147483648");
	BigInt bad ("23487267");
	cout<<((sad-sad)==BigInt(0))<<endl;
	assert((sad-sad)==BigInt(0));

	cout<<((sad*BigInt(2)-bad)==BigInt("4271480029"))<<endl;
	assert((sad*BigInt(2)-bad)==BigInt("4271480029"));

	cout<<((bad-sad)==BigInt("-2123996381"))<<endl;
	assert((bad-sad)==BigInt("-2123996381"));

	BigInt ruar = bad-sad;
	++ruar;

	cout<<((ruar)==BigInt("-2123996380"))<<endl;
	assert((ruar)==BigInt("-2123996380"));
	cout<<endl;

	BigInt sy(2147483647);
	BigInt sum(0);
	for(int i=0; i<5; ++i)
		sum+=sy;
	BigInt cinque(5);
	cout<<((sum == sy*cinque) && sy*cinque == BigInt("10737418235"))<<endl;
	assert((sum == sy*cinque) && sy*cinque == BigInt("10737418235"));
	cout<<endl;

	BigInt sx(111111999);
	sx*=BigInt(99999);
	cout<<(sx==BigInt("11111088788001"))<<endl;
	assert(sx==BigInt("11111088788001"));

	BigInt xx("8877");
	cout<<((pow(xx, 3)==BigInt("699517622133")))<<endl;
	assert((pow(xx, 3)==BigInt("699517622133")));
	cout<<endl;

	//TEST SU DISUGUAGLIANZE
	BigInt x("56756756734350000111100001022003034034");
	BigInt y("223020200200002030934059340593409530459304953049530459340953045930495");

	cout<<"(x!=y) "<<((x!=y)==1)<<endl;
	assert((x!=y)==1);

	cout<<"(x>y) "<<((x>y)==0)<<endl;
	assert((x>y)==0);

	cout<<"(y>x) "<<((y>x)==1)<<endl;
	assert((y>x)==1);

	cout<<"y==y "<<((y==y)==1)<<endl;
	assert((y==y)==1);

	cout<<"(x==y) "<<((x==y==0))<<endl;
	assert((x==y==0));

	BigInt bigboss("8792304289304820934820938420938409234820938423472893748923748923748932748293742893742893742897653225434575");
	cout<<((bigboss == bigboss) == 1)<<endl;
	assert((bigboss == bigboss) == 1);

	bigboss++;
	cout<<((bigboss == bigboss) == 1)<<endl;
	assert((bigboss == bigboss) == 1);
	cout<<endl;

	BigInt aaa ("-387429384729834729384728947293874289347892347");
	BigInt bbb ("387429384729834729384728947293874289347892347");

	cout<<((aaa<bbb)==1)<<endl;
	assert((aaa<bbb)==1);

	cout<<!(aaa==bbb)<<endl;
	assert(!(aaa==bbb));

	cout<<(bbb>=aaa)<<endl;
	assert(bbb>=aaa);

	cout<<((aaa>aaa)==0)<<endl;
	assert((aaa>aaa)==0);

	BigInt minus("-9239482738942738462352537428773289834279879342893427489327493287934287893427893427893427893427489327432879489327893427");
	BigInt minus2("-13287943287943287943287943287989342748932789427387934294287389473287932432879493287493287487932432879879342");

	cout<<((minus<minus2) == 1)<<endl;
	assert((minus<minus2) == 1);

	cout<<!(minus>=minus2)<<endl;
	assert(!(minus>=minus2));

	cout<<!(minus2<minus)<<endl;
	assert(!(minus2<minus));

	cout<<(minus2>minus)<<endl;
	assert(minus2>minus);

	//Divisione
	BigInt allullalo("9287342482348930028734248234893000000000047895622280000121234325478");
	BigInt allillalo("22873424000000000000000000000000000000000000000001212343254789562");
	BigInt result44 = allullalo/allillalo;
	cout<<(result44==BigInt(406))<<endl;
	assert(result44==BigInt(406));

	BigInt dadividere("2147483648");
	BigInt divisore(5);
	cout<<((dadividere/divisore) == BigInt("429496729"))<<endl;
	assert((dadividere/divisore) == BigInt("429496729"));
	cout<<endl;

	////TEST SULLA POTENZA
	BigInt unono(1);
	cout<<((pow(unono, BigInt("9223372036854775807")) == BigInt(1)))<<endl;
	assert((pow(unono, BigInt("9223372036854775807")) == BigInt(1)));

	BigInt xxx("-2147483648");
	BigInt provolas(xxx);
	xxx = pow(xxx,7);
	BigInt moltiplicalo(1);
	for(int i=0; i<7; ++i)
		moltiplicalo*=provolas;

	cout<<(xxx==moltiplicalo)<<endl;
	assert(xxx==moltiplicalo);

	bool errore = false;
	BigInt po("32432432432423423");
	for(int i=0; i<10; ++i)
	{
		BigInt prod(1);
		BigInt prova("32432432432423423");
		for(int j=0; j<i; ++j)
			prod*=prova;

		BigInt questo = pow(po,i);

		if(questo != prod)
		{
			errore = true;
		}

		cout<<(questo == prod)<<endl;
	}
	assert(errore == false);

	////MOLTIPLICAZIONE
	BigInt mul1("1");
	BigInt mul2("-1");
	BigInt p = mul1*mul2;
	cout<<(p == BigInt(-1))<<endl;
	assert(p == BigInt(-1));

	mul1*=BigInt(-1);
	p=mul1*mul2;
	cout<<(p==BigInt(1))<<endl;
	assert(p==BigInt(1));

	mul1*=BigInt(-1);
	p=mul2*mul1;
	cout<<(p==BigInt(-1))<<endl;
	assert(p==BigInt(-1));
	cout<<endl;

	BigInt mul3 ("-2147483648");
	BigInt mul4 ("-238472333409030000000000000000000000000000000000000000000");
	BigInt mul5 ("238472333409030000000000000000000000000000000000000000000");
	p=mul3*mul4;
	cout<<(p>BigInt(0))<<endl;
	assert(p>BigInt(0));

	cout<<(mul3*mul5<BigInt(0))<<endl;
	assert(mul3*mul5<BigInt(0));
	cout<<endl;

	BigInt l ("2309482930482093427834635264263538798911100000000001010101010");
	l*=BigInt(-1);
	cout<<(l==BigInt("-2309482930482093427834635264263538798911100000000001010101010"))<<endl; 
	assert(l==BigInt("-2309482930482093427834635264263538798911100000000001010101010"));
	cout<<endl;

	BigInt fox(993892);
	fox/=BigInt(400);
	cout<<(fox==BigInt(2484))<<endl;
	cout<<endl;

	BigInt a("-456456399");
	BigInt b("2");
	BigInt result = a%b;
	cout<<(BigInt((-456456399)%(2)) == result)<<endl;
	assert(BigInt((-456456399)%(2)) == result);

	int aa = -2147483647;
	int bb = 5;
	BigInt c = BigInt(aa)%BigInt(bb);
	cout<<(BigInt(-2147483647%5) == c)<<endl;
	assert(BigInt(-2147483647%5) == c);


	BigInt laal(-2);
	BigInt provolasse("-2");
	BigInt loooool = pow(laal, 9000);
	BigInt moltiplicalol(1);
	for(int i=0; i<9000; ++i)
		moltiplicalol*=provolasse;
	cout<<(loooool==moltiplicalol)<<endl;
	assert(loooool==moltiplicalol);
	cout<<endl;

	BigInt na("-2287342482348930009991239876012345566");
	BigInt nb("-10000000900001010203000");
	BigInt result1= na/nb;
	BigInt result2 = na%nb;
	cout<<(result1*nb + result2 == na)<<endl;
	assert(result1*nb + result2 == na);

	BigInt idsufhdsiuhdsiu("321323213213213213213213245444421412342141");
	BigInt lollll("32135623");
	BigInt div = idsufhdsiuhdsiu/lollll;
	BigInt div2 = idsufhdsiuhdsiu%lollll;
	cout<<(div*lollll + div2 == idsufhdsiuhdsiu)<<endl;
	assert(div*lollll + div2 == idsufhdsiuhdsiu);

	BigInt e ("999999124981248124192124712941728418412"); 
	BigInt d(-40000000);
	BigInt prova = e/d;
	BigInt resto = e%d;
	cout<<((prova*d)+resto==e)<<endl;
	assert((prova*d)+resto==e);
	cout<<endl;

	BigInt anta ("-2147483648340958340958340958309458340958340958304958304958309458340958340958394085");
	BigInt benta ("214748364800345345345345345300");
	BigInt s = anta/benta;
	BigInt z = anta%benta;
	cout<<(anta == s*benta + z)<<endl;
	assert(anta == s*benta + z);

	cout<<(anta-(s*benta) == z)<<endl;
	assert(anta-(s*benta) == z);

	BigInt w("234928734892734982734982734892734987239482734982739482739487239482734982734");
	BigInt ww(1);
	BigInt q(-2);

	cout<<(w%ww == BigInt(0))<<endl;
	assert(w%ww == BigInt(0));

	cout<<(w%q == BigInt(0))<<endl;
	assert(w%q == BigInt(0));
}